package domain

import (
	"context"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/mars/pkg/errors"
)

// CartStatus 购物车状态枚举
type CartStatus string

const (
	CartStatusActive   CartStatus = "active"   // 有效
	CartStatusInactive CartStatus = "inactive" // 无效
	CartStatusExpired  CartStatus = "expired"  // 过期
)

// CartItem 购物车项
type CartItem struct {
	ID         string     `json:"_id,omitempty" bson:"_id,omitempty"`
	OpenID     string     `json:"openid" bson:"openid"`         // 用户OpenID
	ProductID  string     `json:"productId" bson:"productId"`   // 产品ID
	Quantity   int        `json:"quantity" bson:"quantity"`     // 数量
	Status     CartStatus `json:"status" bson:"status"`         // 状态
	CreateTime int64      `json:"createTime" bson:"createTime"` // 创建时间
	UpdateTime int64      `json:"updateTime" bson:"updateTime"` // 更新时间
	// 扩展字段 - 从产品表关联获取
	ProductInfo *Product `json:"productInfo,omitempty" bson:"-"` // 产品信息（不存储在购物车表）
}

// CartQueryParams 购物车查询参数
type CartQueryParams struct {
	PaginationParams
	SortParams
	OpenID    string     `json:"openid,omitempty"`    // 用户OpenID过滤
	ProductID string     `json:"productId,omitempty"` // 产品ID过滤
	Status    CartStatus `json:"status,omitempty"`    // 状态过滤
	Keyword   string     `json:"keyword,omitempty"`   // 关键字搜索（用户openid、产品名称）
}

// NewDefaultCartQueryParams 创建默认购物车查询参数
func NewDefaultCartQueryParams() CartQueryParams {
	return CartQueryParams{
		PaginationParams: DefaultPaginationParams,
		SortParams:       DefaultSortParams,
	}
}

// CartStats 购物车统计信息
type CartStats struct {
	TotalItems      int64            `json:"totalItems"`      // 总购物车项数
	TotalUsers      int64            `json:"totalUsers"`      // 有购物车的用户数
	ActiveItems     int64            `json:"activeItems"`     // 有效购物车项数
	InactiveItems   int64            `json:"inactiveItems"`   // 无效购物车项数
	ExpiredItems    int64            `json:"expiredItems"`    // 过期购物车项数
	ItemsByStatus   map[string]int64 `json:"itemsByStatus"`   // 按状态统计
	TopProducts     []ProductStat    `json:"topProducts"`     // 热门购物车商品
	AvgItemsPerUser float64          `json:"avgItemsPerUser"` // 每用户平均购物车项数
	TotalQuantity   int64            `json:"totalQuantity"`   // 总商品数量
	ConversionRate  float64          `json:"conversionRate"`  // 购物车转化率（有购物车用户/总用户）
}

// CartValidator 购物车验证器
type CartValidator struct {
	paginationValidator *PaginationValidator
	idValidator         *IDValidator
	stringValidator     *StringValidator
	enumValidator       *EnumValidator
	sortValidator       *SortValidator
}

// NewCartValidator 创建购物车验证器
func NewCartValidator() *CartValidator {
	return &CartValidator{
		paginationValidator: NewPaginationValidator(1000),
		idValidator:         NewIDValidator("cart ID", 1, 128),
		stringValidator:     NewStringValidator("keyword", 100, false),
		enumValidator: NewEnumValidator("status", []string{
			string(CartStatusActive), string(CartStatusInactive), string(CartStatusExpired),
		}, false),
		sortValidator: NewSortValidator([]string{
			"createTime", "updateTime", "quantity",
		}),
	}
}

// ValidateCartID 验证购物车ID
func (cv *CartValidator) ValidateCartID(cxt *gin.Context, paramName string) (string, error) {
	return cv.idValidator.ValidateFromParam(cxt, paramName)
}

// ValidateOpenID 验证用户OpenID
func (cv *CartValidator) ValidateOpenID(cxt *gin.Context, paramName string) (string, error) {
	openid := cxt.Param(paramName)
	if openid == "" {
		openid = cxt.Query(paramName)
	}

	if openid == "" {
		return "", errors.New(http.StatusBadRequest, "openid is required")
	}

	if len(openid) < 1 || len(openid) > 128 {
		return "", errors.New(http.StatusBadRequest, "openid length must be between 1 and 128 characters")
	}

	return openid, nil
}

// ValidateProductID 验证产品ID
func (cv *CartValidator) ValidateProductID(cxt *gin.Context, paramName string) (string, error) {
	productId := cxt.Param(paramName)
	if productId == "" {
		productId = cxt.Query(paramName)
	}

	if productId == "" {
		return "", errors.New(http.StatusBadRequest, "productId is required")
	}

	if len(productId) < 1 || len(productId) > 128 {
		return "", errors.New(http.StatusBadRequest, "productId length must be between 1 and 128 characters")
	}

	return productId, nil
}

// ValidateCartStatus 验证购物车状态
func (cv *CartValidator) ValidateCartStatus(cxt *gin.Context, paramName string) (CartStatus, error) {
	status := cxt.Param(paramName)
	if status == "" {
		status = cxt.Query(paramName)
	}

	if status == "" {
		return "", nil // 状态是可选的
	}

	err := cv.enumValidator.Validate(status)
	if err != nil {
		return "", err
	}

	return CartStatus(status), nil
}

// ValidateQueryParams 验证查询参数
func (cv *CartValidator) ValidateQueryParams(cxt *gin.Context) (CartQueryParams, error) {
	// 验证分页参数
	paginationParams, err := cv.paginationValidator.ValidateAndParse(cxt)
	if err != nil {
		return CartQueryParams{}, err
	}

	// 验证排序参数
	sortParams, err := cv.sortValidator.ValidateAndParse(cxt)
	if err != nil {
		return CartQueryParams{}, err
	}

	// 验证其他参数
	openid := cxt.Query("openid")
	if openid != "" && (len(openid) < 1 || len(openid) > 128) {
		return CartQueryParams{}, errors.New(http.StatusBadRequest, "openid length must be between 1 and 128 characters")
	}

	productId := cxt.Query("productId")
	if productId != "" && (len(productId) < 1 || len(productId) > 128) {
		return CartQueryParams{}, errors.New(http.StatusBadRequest, "productId length must be between 1 and 128 characters")
	}

	status := cxt.Query("status")
	if status != "" {
		err := cv.enumValidator.Validate(status)
		if err != nil {
			return CartQueryParams{}, err
		}
	}

	keyword := cxt.Query("keyword")
	if err := cv.stringValidator.Validate(keyword); err != nil {
		return CartQueryParams{}, err
	}

	return CartQueryParams{
		PaginationParams: paginationParams,
		SortParams:       sortParams,
		OpenID:           openid,
		ProductID:        productId,
		Status:           CartStatus(status),
		Keyword:          keyword,
	}, nil
}

// CartGateway 购物车网关接口
type CartGateway interface {
	// GetCartList 获取购物车列表
	GetCartList(ctx context.Context, params CartQueryParams) ([]CartItem, int64, error)

	// GetCartItem 根据ID获取购物车项详情
	GetCartItem(ctx context.Context, cartID string) (*CartItem, error)

	// GetUserCartItems 获取用户的购物车列表
	GetUserCartItems(ctx context.Context, openid string) ([]CartItem, error)

	// GetCartItemsByProduct 根据产品ID获取购物车项列表
	GetCartItemsByProduct(ctx context.Context, productID string) ([]CartItem, error)

	// GetCartItemsByStatus 根据状态获取购物车项列表
	GetCartItemsByStatus(ctx context.Context, status CartStatus) ([]CartItem, error)

	// GetCartStats 获取购物车统计信息
	GetCartStats(ctx context.Context) (*CartStats, error)

	// SearchCartItems 搜索购物车项
	SearchCartItems(ctx context.Context, keyword string) ([]CartItem, error)
}

// 定义购物车相关错误
var (
	ErrCartItemNotFound      = errors.New(http.StatusNotFound, "购物车项不存在")
	ErrCartOpenIDRequired    = errors.New(http.StatusBadRequest, "用户OpenID不能为空")
	ErrCartProductIDRequired = errors.New(http.StatusBadRequest, "产品ID不能为空")
	ErrCartQuantityInvalid   = errors.New(http.StatusBadRequest, "商品数量必须大于0")
	ErrCartAlreadyExists     = errors.New(http.StatusConflict, "购物车项已存在")
)
